package yxy.cherry.paycenter.servlet.channel.oppo_quick;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jodd.util.StringUtil;
import yxy.apple.logger.Logger;
import yxy.apple.util.SdkUtil;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.charge;
import yxy.cherry.paycenter.channelmodule.ActType;
import yxy.cherry.paycenter.channelmodule.sdk_oppo_quick.PayMoudle_oppo_quick;
import yxy.cherry.paycenter.database.dao.orderinfoDao;
import yxy.cherry.paycenter.database.dao.ordersDao;
import yxy.cherry.paycenter.database.db.orderinfo;
import yxy.cherry.paycenter.database.db.orders;
import yxy.cherry.paycenter.servlet.channel.Servlet;
import yxy.cherry.paycenter.util.HttpUtil;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.channel.SdkChannel;
import yxy.game.pm2.bean.db.sdk.SDK_UnionChannel;
import yxy.game.pm2.bean.db.sdk.SDK_UnionChannelDAO;
import yxy.game.pm2.bean.module.OrderInfoModule;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

//oppo快游戏，支付结果通知
public class Servlet_oppo_quick extends Servlet{
	private static final Logger logger = Logger.create(Servlet_oppo_quick.class);
	@Override
	public String getChannel() {
		return SdkChannel.sdk_oppo_quick;
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doGet(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		JSONObject rjson = new JSONObject();
		String SUCCESS = "result=OK&resultMsg=成功";
		String FAIL = "result=FAIL&resultMsg=";
		try {
			HttpUtil.printlnParseMap("post", req);
			JSONObject json = HttpUtil.getParseJSON(req);
			logger.info(SdkChannel.sdk_oppo_quick + ":notify:" + json);

			String notifyId = json.getString("notifyId");
			String partnerOrder = json.getString("partnerOrder"); //我方订单号
			String productName = json.getString("productName");
			String productDesc = json.getString("productDesc");
			String price = json.getString("price"); //分
			String count = json.getString("count");
			String attach = json.getString("attach"); //传的是appid
			String paymentWay = json.getString("paymentWay");
			String payResult = json.getString("payResult");
			String sign = json.getString("sign");

			//基础参数校验
			if (StringUtil.isAllEmpty(partnerOrder, price, sign))
				throw new Exception("参数异常");

			//插入orderinfo表
			orderinfo oinfo = new orderinfo();
			oinfo.setMyorderid(partnerOrder);
			oinfo.setOtherinfo(json.toString());
			orderinfoDao.add(oinfo);

			//渠道参数核对
			SDK_UnionChannel unionChannel = SDK_UnionChannelDAO.getByAppId(SdkChannel.sdk_oppo_quick, attach);
			if (unionChannel == null) throw new Exception("渠道异常");
			//订单核对，是否存在
			orders o = ordersDao.getOrderByMyorderid(partnerOrder);
			if (o == null) throw new Exception("订单不存在");
			//已经是成功的订单，不用重复处理
			if (o.getOrderstate() == 1) {
				returnInfo(SUCCESS, resp);
				return;
			}
			//金额核对
			int fee = Integer.parseInt(price);
			if (fee != o.getGoodsprice()) throw new Exception("amount error");

			//sign校验
			Map<String, String> params = json.toJavaObject(Map.class);
			params.remove("sign");
			String signContent = SdkUtil.mapToContent(params, true);
			logger.info(SdkChannel.sdk_oppo_quick + ":sign:%s,%s,%s,%s", JSON.toJSON(params), signContent);
			boolean chkres = doCheck(signContent, sign, unionChannel.getPublicKey());
			if (!chkres) throw new Exception("签名错误");

			o.setPlatorderid(notifyId);
			o.setUpdatetime(new Date());
			o.setPayamount(fee);
			o.setOrderstate(OrderInfoModule.orderinfofinish);
			ordersDao.update(o);

			ActType at = ActType.getat(o.getActtype());
//		PayType pt = PayType.getpt(at.getPaytype());
			PayMoudle_oppo_quick am = new PayMoudle_oppo_quick();
			ArrayList<Currency> curs = am.getRewardInfoByType(o.getPlayercode(), at, o.getGoodsid());

			charge charge = DataCenter.getData(o.getGoodsid(), charge.class);
			am.createOrderInfoModule(o, curs, charge.getVipexp(), o.getGoodsprice());

			returnInfo(SUCCESS, resp);
		} catch (Exception e) {
			logger.error(SdkChannel.sdk_oppo_quick + ":sign error:%s", e);
			e.printStackTrace();
			returnInfo(FAIL + e.getMessage(), resp);
		}
	}

	public static boolean doCheck(String content, String sign, String publicKey) {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey =  org.apache.commons.codec.binary.Base64.decodeBase64(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
			java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
			signature.initVerify(pubKey);
			signature.update(content.getBytes("utf-8"));
			boolean bverify = signature.verify(org.apache.commons.codec.binary.Base64.decodeBase64(sign));
			return bverify;
		} catch (Exception e) {
			logger.error("验证签名出错.",e);
		}
		return false;
	}
}
